package com.dyp.websocket.endpoint;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ServerEndpoint(value="/imserver/{userId}")
public class IMServer {
    private static ConcurrentHashMap<String, IMServer> imSocketServerMap = new ConcurrentHashMap<>();
    private Session session;
    private String userId;

    private static int onlineCount = 0;

    public static synchronized int getOnlineCount(){
        return onlineCount;
    }

    public static synchronized void addOnlineCount(){
        IMServer.onlineCount++;
    }

    public static synchronized void subOnlineCount(){
        IMServer.onlineCount--;
    }
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) throws IOException
    {
        System.out.println("onOpen:" + userId);
        this.session = session;
        this.userId = userId;

        if(imSocketServerMap.containsKey(userId)){
            //每一次建立连接都会创建一个新的IMServer所以，需要更新对应的WebSocket
            //userId重复出现可以理解成重新登录
            imSocketServerMap.get(userId).session.close(); //释放老的
            imSocketServerMap.put(userId,this); //添加新的
        }
        else{
            imSocketServerMap.put(userId,this);
            addOnlineCount();
        }

        try{
            sendMessage("connect success");
        }catch (IOException e){
            e.printStackTrace();
        }


    }

    @OnClose
    public void onClose(@PathParam("userId") String userId, Session session) throws IOException
    {
        System.out.println("onOpen:" + userId);
        if(imSocketServerMap.containsKey(userId))
        {
            imSocketServerMap.remove(userId);
            subOnlineCount();
        }
        System.out.println(session.getUserProperties().get("userId") + "close");
    }

    @OnError
    public void onError(Session session, Throwable error){
        System.out.println("onError");
        error.printStackTrace();
    }

    @OnMessage
    public void textMessage(Session session, String msg){
        System.out.println("textMessage:" + msg);
        if(StringUtils.hasLength(msg)){
            //解析双方协定好的协议
            JSONObject jsonObject = JSON.parseObject(msg);
            String toUserId = jsonObject.getString("toUserId");
            if(StringUtils.hasLength(toUserId) && imSocketServerMap.containsKey(toUserId)){
                try {
                    imSocketServerMap.get(toUserId).sendMessage(jsonObject.toJSONString());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }else {
                System.out.println(toUserId + " not existed in this server");
            }
        }
    }

    @OnMessage
    public void binaryMessage(Session session, ByteBuffer msg){
        System.out.println("binaryMessage:" + msg.toString());
    }

    @OnMessage
    public void pongMessage(Session session, PongMessage msg){
        System.out.println("pongMessage:" + msg.getApplicationData().toString());
    }

    public void sendMessage(String message) throws IOException{
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 后端向前端发送数据
     */
    public static void backendSendInfoToUser(String message, String userId) throws IOException{
        System.out.println(userId + " send " + message);
        if(StringUtils.hasLength(userId) && imSocketServerMap.containsKey(userId)){
            imSocketServerMap.get(userId).sendMessage(message);
        }else {
            System.out.println(userId + " not existed in this server");
        }
    }
}
